import numpy as np
from sklearn import datasets
from sklearn.linear_model import LinearRegression, LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB
from sklearn.neighbors import KNeighborsClassifier
import pandas as pd

from sklearn.metrics import accuracy_score

pd.set_option('display.max_rows', 500)
pd.set_option('display.max_columns', 500)
pd.set_option('display.width', 1000)


# pd.set_option('display.index', False)
def load_football(league, start_date, end_date):
    # 预处理数据
    df = pd.read_csv("d3.csv", encoding="UTF-8",
                     usecols=["比赛时间", "联赛", "胜临", "平临", "负临", "赛果"], header=0, low_memory=False)
    df = df.dropna()

    df['比赛时间'] = pd.to_datetime(df['比赛时间'])
    df = df[(df['比赛时间'] >= start_date) & (df['比赛时间'] <= end_date)]

    df_unique_league = df["联赛"].value_counts()
    # print(f"联赛：{df_unique_league}")

    if league != "":
        df = df[df['联赛'] == league]

    df = df.drop("联赛", axis=1).drop("比赛时间", axis=1)

    df["赛果"] = df["赛果"].replace("负", 1).replace("平", 2).replace("胜", 3)

    # 区分训练数据以及验证数据
    train_size = int(len(df) * 0.8)
    train, test = df[:train_size], df[train_size:]

    x_train = train.drop("赛果", axis=1)
    y_train = train["赛果"]

    x_true = test.drop("赛果", axis=1)
    y_true = test["赛果"]

    return x_train, y_train, x_true, y_true


def predict_knn(x_train, y_train, x_true, y_true):
    # KNN算法
    knn = KNeighborsClassifier()
    knn.fit(x_train, y_train)
    y_pred = knn.predict(x_true)
    accuracy = accuracy_score(y_true.values, y_pred)
    # print(f'KNN：{accuracy}')
    df9 = x_true.copy()
    df9["y_pred"] = y_pred
    df9["y_true"] = y_true
    # print(df9.tail())
    return accuracy


def predict_linear(x_train, y_train, x_true, y_true):
    # Linear
    linear = LinearRegression()
    linear.fit(x_train, y_train)
    y_pred = linear.predict(x_true)
    y_pred_int = np.round(y_pred).astype(int)

    df9 = x_true.copy()
    df9["y_pred"] = y_pred
    df9["y_pred_int"] = y_pred_int
    df9["y_true"] = y_true
    # print(df9.tail())
    accuracy = accuracy_score(y_true.values, y_pred_int)
    # print(f'LINER：{accuracy}')
    return accuracy


def predict_Logistic(x_train, y_train, x_true, y_true):
    logistic = LogisticRegression(solver="liblinear", C=100)
    logistic.fit(x_train, y_train)
    y_pred = logistic.predict(x_true)
    accuracy = accuracy_score(y_true.values, y_pred)
    # print(f'Logistic：{accuracy}')
    df9 = x_true.copy()
    df9["y_pred"] = y_pred
    df9["y_true"] = y_true
    # print(df9.tail())
    return accuracy


def predict_bayes(x_train, y_train, x_true, y_true):
    gaussiannb = GaussianNB()
    gaussiannb.fit(x_train, y_train)
    y_pred = gaussiannb.predict(x_true)
    accuracy = accuracy_score(y_true.values, y_pred)
    return accuracy


def run(start_date, end_date):
    df = pd.read_csv("d3.csv", encoding="UTF-8", usecols=["比赛时间", "联赛", "胜临", "平临", "负临", "赛果"], header=0,
                     low_memory=False)
    df = df.dropna()

    df['比赛时间'] = pd.to_datetime(df['比赛时间'])
    df = df[(df['比赛时间'] >= start_date) & (df['比赛时间'] <= end_date)]

    df_unique_league = df["联赛"].value_counts()
    top_leagues = df_unique_league[:20].keys()
    for league in top_leagues:
        x_train, y_train, x_true, y_true = load_football(league, start_date, end_date)
        accuracy_knn = predict_knn(x_train, y_train, x_true, y_true)
        accuracy_linear = predict_linear(x_train, y_train, x_true, y_true)
        accuracy_logistic = predict_Logistic(x_train, y_train, x_true, y_true)
        accuracy_bayes = predict_bayes(x_train, y_train, x_true, y_true)
        print(
            f'{league} {start_date} {end_date} knn:{round(accuracy_knn, 2)} linear:{round(accuracy_linear, 2)} logistic:{round(accuracy_logistic, 2)} '
            f'bayes:{round(accuracy_bayes, 2)}')


def predict():
    start_date = "2023-01-01"
    end_date = "2024-07-01"
    league = "英超"
    df = pd.read_csv("d3.csv", encoding="UTF-8", usecols=["比赛时间", "联赛", "胜临", "平临", "负临", "赛果"], header=0,
                     low_memory=False)
    df = df.dropna()

    df['比赛时间'] = pd.to_datetime(df['比赛时间'])
    df = df[(df['比赛时间'] >= start_date) & (df['比赛时间'] <= end_date)]

    if league != "":
        df = df[df['联赛'] == league]

    df = df.drop("联赛", axis=1).drop("比赛时间", axis=1)
    df["赛果"] = df["赛果"].replace("负", -1).replace("平", 0).replace("胜", 1)

    # 区分训练数据以及验证数据
    train_size = int(len(df) * 0.8)
    train, test = df[:train_size], df[train_size:]

    x_train = train.drop("赛果", axis=1)
    y_train = train["赛果"]

    x_true = test.drop("赛果", axis=1)
    y_true = test["赛果"]

    gaussiannb = GaussianNB()
    gaussiannb.fit(x_train, y_train)
    y_pred = gaussiannb.predict(x_true)
    accuracy = accuracy_score(y_true.values, y_pred)
    # return accuracy
    df9 = pd.read_csv("0802.cvs", encoding="UTF-8", header=0, usecols=["胜临", "平临", "负临"], low_memory=False)
    x_cvs = df9
    y_pred = gaussiannb.predict(x_cvs)
    print(y_pred)


# run("2023-01-01", "2024-07-01")
predict()
